{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Robot Bounded In Circle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Medium"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #math #string #simulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #数学 #字符串 #模拟"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: isRobotBounded"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #困于环中的机器人"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>在无限的平面上，机器人最初位于&nbsp;<code>(0, 0)</code>&nbsp;处，面朝北方。注意:</p>\n",
    "\n",
    "<ul>\n",
    "\t<li><strong>北方向</strong> 是y轴的正方向。</li>\n",
    "\t<li><strong>南方向</strong> 是y轴的负方向。</li>\n",
    "\t<li><strong>东方向</strong> 是x轴的正方向。</li>\n",
    "\t<li><strong>西方向</strong> 是x轴的负方向。</li>\n",
    "</ul>\n",
    "\n",
    "<p>机器人可以接受下列三条指令之一：</p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>\"G\"</code>：直走 1 个单位</li>\n",
    "\t<li><code>\"L\"</code>：左转 90 度</li>\n",
    "\t<li><code>\"R\"</code>：右转 90 度</li>\n",
    "</ul>\n",
    "\n",
    "<p>机器人按顺序执行指令&nbsp;<code>instructions</code>，并一直重复它们。</p>\n",
    "\n",
    "<p>只有在平面中存在环使得机器人永远无法离开时，返回&nbsp;<code>true</code>。否则，返回 <code>false</code>。</p>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>instructions = \"GGLLGG\"\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>机器人最初在(0,0)处，面向北方。\n",
    "“G”:移动一步。位置:(0,1)方向:北。\n",
    "“G”:移动一步。位置:(0,2).方向:北。\n",
    "“L”:逆时针旋转90度。位置:(0,2).方向:西。\n",
    "“L”:逆时针旋转90度。位置:(0,2)方向:南。\n",
    "“G”:移动一步。位置:(0,1)方向:南。\n",
    "“G”:移动一步。位置:(0,0)方向:南。\n",
    "重复指令，机器人进入循环:(0,0)——&gt;(0,1)——&gt;(0,2)——&gt;(0,1)——&gt;(0,0)。\n",
    "在此基础上，我们返回true。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>instructions = \"GG\"\n",
    "<strong>输出：</strong>false\n",
    "<strong>解释：</strong>机器人最初在(0,0)处，面向北方。\n",
    "“G”:移动一步。位置:(0,1)方向:北。\n",
    "“G”:移动一步。位置:(0,2).方向:北。\n",
    "重复这些指示，继续朝北前进，不会进入循环。\n",
    "在此基础上，返回false。\n",
    "</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>instructions = \"GL\"\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>机器人最初在(0,0)处，面向北方。\n",
    "“G”:移动一步。位置:(0,1)方向:北。\n",
    "“L”:逆时针旋转90度。位置:(0,1).方向:西。\n",
    "“G”:移动一步。位置:(- 1,1)方向:西。\n",
    "“L”:逆时针旋转90度。位置:(- 1,1)方向:南。\n",
    "“G”:移动一步。位置:(- 1,0)方向:南。\n",
    "“L”:逆时针旋转90度。位置:(- 1,0)方向:东方。\n",
    "“G”:移动一步。位置:(0,0)方向:东方。\n",
    "“L”:逆时针旋转90度。位置:(0,0)方向:北。\n",
    "重复指令，机器人进入循环:(0,0)——&gt;(0,1)——&gt;(- 1,1)——&gt;(- 1,0)——&gt;(0,0)。\n",
    "在此基础上，我们返回true。</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= instructions.length &lt;= 100</code></li>\n",
    "\t<li><code>instructions[i]</code>&nbsp;仅包含&nbsp;<code>'G', 'L', 'R'</code></li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [robot-bounded-in-circle](https://leetcode.cn/problems/robot-bounded-in-circle/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [robot-bounded-in-circle](https://leetcode.cn/problems/robot-bounded-in-circle/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['\"GGLLGG\"', '\"GG\"', '\"GL\"']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direc = [[0, 1], [1, 0], [0, -1], [-1, 0]]\n",
    "        direcIndex = 0\n",
    "        x, y = 0, 0\n",
    "        for instruction in instructions:\n",
    "            if instruction == 'G':\n",
    "                x += direc[direcIndex][0]\n",
    "                y += direc[direcIndex][1]\n",
    "            elif instruction == 'L':\n",
    "                direcIndex -= 1\n",
    "                direcIndex %= 4\n",
    "            else:\n",
    "                direcIndex += 1\n",
    "                direcIndex %= 4\n",
    "        return direcIndex != 0 or (x == 0 and y == 0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        def move(idx, x, y, direction):\n",
    "            if idx >= len(instructions):\n",
    "                return x,y\n",
    "            inst = instructions[idx]\n",
    "            if inst == 'L':\n",
    "                direction = turning_left_dict[direction]\n",
    "            elif inst == 'R':\n",
    "                direction = turning_right_dict[direction]\n",
    "            elif inst == 'G':\n",
    "                path.append([x,y])\n",
    "                if direction == 'north':\n",
    "                    y -= 1\n",
    "                elif direction == 'west':\n",
    "                    x -= 1 \n",
    "                elif direction == 'south':\n",
    "                    y += 1 \n",
    "                elif direction == 'east':\n",
    "                    x += 1 \n",
    "            return move(idx+1, x, y, direction)\n",
    "\n",
    "        path = []\n",
    "        instructions *= 4\n",
    "        turning_left_dict = {\n",
    "            'north':'west', 'west':'south', 'south':'east', 'east':'north'\n",
    "            }\n",
    "        turning_right_dict = {\n",
    "            'north':'east', 'east':'south', 'south':'west', 'west':'north'\n",
    "            }\n",
    "        return move(0, 0, 0, 'north') == (0,0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        distance_lst = [[0, 1], [1, 0], [0, -1], [-1, 0]]\n",
    "        d = 0\n",
    "        x, y = 0, 0\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x += distance_lst[d][0]\n",
    "                y += distance_lst[d][1]\n",
    "            elif i == 'L':\n",
    "                d = (d-1) % 4\n",
    "            elif i == 'R':\n",
    "                d = (d+1) % 4\n",
    "        return (x == 0 and y == 0) or d != 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        d = [[0, 1], [1, 0], [0, -1], [-1, 0]]\n",
    "        i = 0\n",
    "        x, y = 0, 0\n",
    "        for inst in instructions:\n",
    "            if inst == 'G':\n",
    "                x += d[i][0]\n",
    "                y += d[i][1]\n",
    "            elif inst == 'L':\n",
    "                i = (i-1)%4\n",
    "            else:\n",
    "                i = (i+1)%4\n",
    "        return i != 0 or (x == 0 and y == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        directions = ['N', 'E', 'S', 'W']\n",
    "        direction = 0\n",
    "        location = [0, 0]\n",
    "        # key results is \n",
    "        for instruction in instructions:\n",
    "            if instruction == \"G\":\n",
    "                match directions[direction]:\n",
    "                    case \"N\":\n",
    "                        location[1] += 1\n",
    "                    case \"S\":\n",
    "                        location[1] -= 1\n",
    "                    case \"W\":\n",
    "                        location[0] -= 1\n",
    "                    case \"E\":\n",
    "                        location[0] += 1\n",
    "                    case _:\n",
    "                        print(f\"Warning: Invalid input: {directions[direction]}.\")\n",
    "            elif instruction == \"L\":\n",
    "                direction -= 1\n",
    "                if direction == -1:\n",
    "                    direction = 3\n",
    "            elif instruction == \"R\":\n",
    "                direction += 1\n",
    "                if direction == 4:\n",
    "                    direction = 0\n",
    "        return directions[direction] != \"N\" or location == [0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        cord_x,cord_y=0,0\n",
    "        direction=0\n",
    "        def moveG(x,y,direction):\n",
    "            if direction ==0:\n",
    "                y+=1\n",
    "            elif direction==1:\n",
    "                x+=1\n",
    "            elif direction==2:\n",
    "                y-=1\n",
    "            elif direction==3:\n",
    "                x-=1\n",
    "            return x,y\n",
    "\n",
    "        for action in instructions:\n",
    "            if action == 'G':\n",
    "                cord_x,cord_y = moveG(cord_x,cord_y,direction)\n",
    "            elif action =='L':\n",
    "                direction-=1\n",
    "                if direction==-1:\n",
    "                    direction=3\n",
    "            elif action =='R':\n",
    "                direction+=1\n",
    "                if direction ==4:\n",
    "                    direction=0\n",
    "        if direction==0 and (cord_x!=0 or cord_y!=0):\n",
    "            return False\n",
    "        else:\n",
    "            return True\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        pos = [0, 0]\n",
    "        directions = [[0, 1], [-1, 0], [0, -1], [1, 0]]\n",
    "        direction_index = 0\n",
    "        for char in instructions:\n",
    "            if char == 'G':\n",
    "                pos[0] += directions[direction_index][0]\n",
    "                pos[1] += directions[direction_index][1]\n",
    "            elif char == 'L':\n",
    "                direction_index = (direction_index + 1) % 4\n",
    "            elif char == 'R':\n",
    "                direction_index = (direction_index - 1) % 4\n",
    "        if pos == [0, 0]:\n",
    "            return True\n",
    "        elif direction_index != 0:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k = 0\n",
    "        dist = [0]*4\n",
    "        for s in instructions:\n",
    "            if s == 'L':\n",
    "                k += 1\n",
    "                k %= 4\n",
    "            elif s == 'R':\n",
    "                k -= 1\n",
    "                k %= 4\n",
    "            else:\n",
    "                dist[k] += 1\n",
    "        return (dist[0] == dist[2] and dist[1] == dist[3]) or k != 0\n",
    "\n",
    "\n",
    "                        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        n=0\n",
    "        x=[0,0]\n",
    "        for i in instructions:\n",
    "            if i==\"L\":\n",
    "                n+=1\n",
    "            elif i==\"R\":\n",
    "                n-=1\n",
    "            else:\n",
    "                n%=4\n",
    "                if n==0:\n",
    "                    x[1]+=1\n",
    "                elif n==2:\n",
    "                    x[1]-=1\n",
    "                elif n==1:\n",
    "                    x[0]+=1\n",
    "                else:\n",
    "                    x[0]-=1\n",
    "        if (x!=[0,0]) and (n%4==0):\n",
    "            return False\n",
    "        else:\n",
    "            return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direction = [[0, 1], [1, 0], [0, -1], [-1, 0]]      # 方向北西南东\n",
    "        dirIndex = 0\n",
    "        x, y = 0, 0\n",
    "        for instruction in instructions:\n",
    "            if instruction == 'G':\n",
    "                x += direction[dirIndex][0]\n",
    "                y += direction[dirIndex][1]\n",
    "            elif instruction == 'L':\n",
    "                dirIndex -= 1\n",
    "                dirIndex %= 4\n",
    "            else:\n",
    "                dirIndex += 1\n",
    "                dirIndex %= 4\n",
    "            \n",
    "        if dirIndex == 0 and (x != 0 or y != 0):\n",
    "            return False\n",
    "        return True\n",
    "        \n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dic = {0:[0,1], 1:[-1,0], 2:[0,-1], 3:[1,0]}\n",
    "        i,j = 0,0\n",
    "        tmp = [0,1]\n",
    "        num = 0\n",
    "        for r in range(4):\n",
    "            for x in instructions:\n",
    "                if x == \"L\":\n",
    "                    num += 1\n",
    "                    tmp = dic[num%4]\n",
    "                elif x == \"R\":\n",
    "                    num -= 1\n",
    "                    tmp = dic[num%4]\n",
    "                else:\n",
    "                    i += tmp[0]\n",
    "                    j += tmp[1]\n",
    "            \n",
    "            if i == j == 0:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        face = [[0,1],[1,0],[0,-1],[-1,0]]\n",
    "        now_face = 0\n",
    "        now_x,now_y = 0,0\n",
    "        data = [(0,0)]\n",
    "        for op in instructions:\n",
    "                if op == 'G':\n",
    "                    d_x,d_y = face[now_face]\n",
    "                    now_x += d_x\n",
    "                    now_y += d_y\n",
    "                if op == 'R':\n",
    "                    now_face += 1\n",
    "                    now_face = (now_face+4) % 4\n",
    "                if op == 'L':\n",
    "                    now_face -= 1\n",
    "                    now_face = (now_face+4) % 4\n",
    "            \n",
    "        return now_face != 0 or (now_x == 0 and now_y == 0)\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # dist表示四个方向移动的距离，分别为：北，西，南，东\n",
    "        dist = [0,0,0,0]\n",
    "        # k表示朝向，分别为：0——北，1——西，2——南，3——东\n",
    "        k = 0\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                dist[k]+=1\n",
    "            elif i == 'L':\n",
    "                k = (k+1)%4\n",
    "            elif i == 'R':\n",
    "                k = (k+3)%4\n",
    "        if dist[0]==dist[2] and dist[1]==dist[3] or k!=0:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOVE = ((0, 1), (1, 0), (0, -1), (-1, 0))\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x = y = 0\n",
    "        dire = 0   # 朝向\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x += MOVE[dire][0]\n",
    "                y += MOVE[dire][1]\n",
    "            elif i == 'R':\n",
    "                dire = (dire + 1) % 4\n",
    "            else:\n",
    "                dire = (dire - 1) % 4\n",
    "        return dire != 0 or x == y == 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        instructions = instructions * 4\n",
    "        direction = 0\n",
    "        position = [0, 0, 0, 0]\n",
    "        for pace in instructions:\n",
    "            match pace:\n",
    "                case \"G\":\n",
    "                    position[direction%4] += 1\n",
    "                case \"L\":\n",
    "                    direction -= 1\n",
    "                case \"R\":\n",
    "                    direction += 1\n",
    "        print(position)\n",
    "        if position[0] - position[2] == 0 and position[1] - position[3] == 0:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]\n",
    "class Solution:\n",
    "    \n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        #判断是否进入循环: 1.向量为0向量\n",
    "        #                 2.向量乘方向得0\n",
    "        #           false:1.向量乘方向不为0\n",
    "        d = 0\n",
    "        place = [0, 0]\n",
    "        for ins in instructions:\n",
    "            if ins == 'G':\n",
    "                place[0] += directions[d % 4][0]\n",
    "                place[1] += directions[d % 4][1]\n",
    "            elif ins == 'R':\n",
    "                d += 1\n",
    "            elif ins == 'L':\n",
    "                d -= 1\n",
    "            #print(place)\n",
    "        direction_vector = directions[d % 4]\n",
    "        place_vector = place\n",
    "        dot = place_vector[0] * direction_vector[0] + place_vector[1] * direction_vector[1]\n",
    "        #print(place_vector, direction_vector)\n",
    "        #print(dot)\n",
    "        if place == [0, 0] or direction_vector != [0, 1]:\n",
    "            return True\n",
    "        return False\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, s: str) -> bool:\n",
    "        x, y, d = 0, 0, 0\n",
    "        dirs = [[0, 1], [-1, 0], [0, -1], [1, 0]]\n",
    "        for c in s:\n",
    "            match c:\n",
    "                case 'G':\n",
    "                    x += dirs[d][0]\n",
    "                    y += dirs[d][1]\n",
    "                case 'L':\n",
    "                    d = (d + 1) % 4\n",
    "                case 'R':\n",
    "                    d = ((d - 1) % 4 + 4) % 4\n",
    "        return (x == 0 and y == 0) or d != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        A = [0,0]  #北西南东\n",
    "        dir = 0\n",
    "        for i in instructions:\n",
    "            if i == 'L':\n",
    "                dir = (dir+1)&3\n",
    "            elif i == 'R':\n",
    "                dir = (dir-1)&3\n",
    "            else:\n",
    "                if dir == 0: A[0] += 1\n",
    "                if dir == 1: A[1] -= 1\n",
    "                if dir == 2: A[0] -= 1\n",
    "                if dir == 3: A[1] += 1\n",
    "        return A==[0,0] or dir!=0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x = y = 0\n",
    "        d = (0, 1)\n",
    "        for c in instructions:\n",
    "            if c == 'G':\n",
    "                x, y = x + d[0], y + d[1]\n",
    "            elif c =='L':\n",
    "                d = (-d[1], d[0])\n",
    "            else:\n",
    "                d = (d[1], -d[0])\n",
    "        return (x == 0 and y == 0) or d != (0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # 0,1,2,3  上左下右\n",
    "        move = [[0,1],[-1,0],[0,-1],[1,0]]\n",
    "        cnt = 0\n",
    "        pos = [0,0]\n",
    "        \n",
    "        for i in instructions:\n",
    "            if i==\"L\":\n",
    "                cnt += 1\n",
    "                cnt %= 4\n",
    "            elif i==\"R\":\n",
    "                cnt -= 1\n",
    "                cnt %= 4\n",
    "            else:\n",
    "                pos[0] += move[cnt][0]\n",
    "                pos[1] += move[cnt][1]\n",
    "        print(cnt, pos)\n",
    "        if cnt==0 and pos!=[0,0]:\n",
    "            return False\n",
    "        else:\n",
    "            return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dx = [0, 1, 0,  -1]\n",
    "        dy = [1, 0, -1, 0]\n",
    "        x , y = 0, 0\n",
    "        fx = 0 #北 \n",
    "        for i in range(4):\n",
    "            for c in instructions:\n",
    "                if c == 'G':\n",
    "                    x += dx[fx]\n",
    "                    y += dy[fx]\n",
    "                elif c == 'L':\n",
    "                    fx = (fx - 1)%4\n",
    "                elif c == 'R':\n",
    "                    fx = (fx + 1)%4\n",
    "        if x == 0 and y == 0 :\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        LL=dict()\n",
    "        RR=dict()\n",
    "        LL[str([0,1])]=[-1,0]\n",
    "        LL[str([-1,0])]=[0,-1]\n",
    "        LL[str([0,-1])]=[1,0]\n",
    "        LL[str([1,0])]=[0,1]\n",
    "        RR[str([0,1])]=[1,0]\n",
    "        RR[str([1,0])]=[0,-1]\n",
    "        RR[str([0,-1])]=[-1,0]\n",
    "        RR[str([-1,0])]=[0,1]\n",
    "        dire=[0,1]\n",
    "        ls=[0,0]\n",
    "        pp=instructions\n",
    "        for each in pp:\n",
    "            if each==\"G\":\n",
    "                ls[0]+=dire[0]\n",
    "                ls[1]+=dire[1]\n",
    "            if each==\"L\":\n",
    "                dire=LL[str(dire)]\n",
    "            if each==\"R\":\n",
    "                dire=RR[str(dire)]\n",
    "        return ls==[0,0] or not (dire==[0,1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direc = [[0, 1], [1, 0], [0, -1], [-1, 0]]\n",
    "        direcIndex = 0\n",
    "        x, y = 0, 0\n",
    "        for instruction in instructions:\n",
    "            if instruction == 'G':\n",
    "                x += direc[direcIndex][0]\n",
    "                y += direc[direcIndex][1]\n",
    "            elif instruction == 'L':\n",
    "                direcIndex -= 1\n",
    "                direcIndex %= 4\n",
    "            else:\n",
    "                direcIndex += 1\n",
    "                direcIndex %= 4\n",
    "        return direcIndex != 0 or (x == 0 and y == 0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        a=b=c=0\n",
    "        for i in instructions:\n",
    "            if i=='L':\n",
    "                c+=1\n",
    "            elif i=='R':\n",
    "                c-=1\n",
    "            elif i=='G':\n",
    "                if c==0:\n",
    "                    b+=1\n",
    "                elif c==1:\n",
    "                    a-=1\n",
    "                elif c==2:\n",
    "                    b-=1\n",
    "                elif c==3:\n",
    "                    a+=1\n",
    "            c=c%4\n",
    "        if a==0 and b==0 or c!=0:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        location = [0, 0]\n",
    "        direciton = 1\n",
    "        for i in instructions:\n",
    "            if i == 'L':\n",
    "                if direciton == 4:\n",
    "                    direciton = 1\n",
    "                else:\n",
    "                    direciton += 1\n",
    "            if i == 'R':\n",
    "                if direciton == 1:\n",
    "                    direciton = 4\n",
    "                else:\n",
    "                    direciton -= 1\n",
    "            if i == 'G':\n",
    "                if direciton == 1:\n",
    "                    location[1] += 1\n",
    "                elif direciton == 2:\n",
    "                    location[0] -= 1\n",
    "                elif direciton == 3:\n",
    "                    location[1] -= 1\n",
    "                else:\n",
    "                    location[0] += 1\n",
    "        if location == [0, 0] or direciton != 1:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direct = 0  \n",
    "        x = 0       \n",
    "        y = 0   \n",
    "        for char in instructions:\n",
    "            if char == 'G':\n",
    "                if direct == 0:\n",
    "                    y += 1  \n",
    "                elif direct == 1:\n",
    "                    x -= 1  \n",
    "                elif direct == 2:\n",
    "                    y -= 1  \n",
    "                else:\n",
    "                    x += 1  \n",
    "            elif char == 'L':\n",
    "                direct = (direct + 1) % 4\n",
    "            else:\n",
    "                direct = (direct + 3) % 4\n",
    "        return (x == 0 and y == 0) or direct != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "dr = [[0,1], [1, 0], [0,-1], [-1, 0]]\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        ortidr = 0\n",
    "        x, y = 0, 0\n",
    "\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x, y = x + dr[ortidr][0], y + dr[ortidr][1]\n",
    "            elif i == 'L':\n",
    "                ortidr -= 1\n",
    "                ortidr %= 4\n",
    "            elif i == 'R':\n",
    "                ortidr += 1\n",
    "                ortidr %= 4\n",
    "        # 如果最终会到原点 那一定是困住了\n",
    "        # 如果方向与原来不一样，通过n 次操作依然会回到原点\n",
    "        return ortidr != 0 or (x == 0 and y == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # k 表示方向，初始值为 0，表示机器人面向北方。变量 k 的取值范围为 [0,3]，分别表示机器人面向北、西、南、东\n",
    "        k = 0\n",
    "        dist = [0, 0, 0, 0]\n",
    "        # 执行一遍后，机器人没回到原点\n",
    "        # 若 k=1，即机器人面向西方，那么机器人执行第二遍指令后，坐标变化量是 (−y,x)\n",
    "        # 继续执行第三遍执行后，坐标变化量是 (−x,−y)\n",
    "        # 继续执行第四遍指令后，坐标变化量是 (y,−x)\n",
    "        # 累加这些坐标变化量，我们可以发现，机器人最终会回到原点 (0,0)\n",
    "\n",
    "        for i in instructions:\n",
    "            if i == 'L':\n",
    "                k = (k + 1) % 4\n",
    "            elif i == 'R':\n",
    "                k = (k + 3) % 4\n",
    "            else:\n",
    "                dist[k] += 1\n",
    "        # 机器人回到了原点，或者机器人的方向与初始方向不同，那么机器人一定会进入循环\n",
    "        return (dist[0] == dist[2] and dist[1] == dist[3]) or k != 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x, y, k = 0, 0, 0\n",
    "        dir = ((0, 1), (-1, 0), (0, -1), (1, 0))\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x += dir[k][0]\n",
    "                y += dir[k][1]\n",
    "            elif i == 'L':\n",
    "                k = (k + 1) % 4\n",
    "            else:\n",
    "                k = ((k - 1) % 4 + 4) % 4\n",
    "        return x == 0 and y == 0 or k != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]\n",
    "        dirsIndex = 0\n",
    "        x, y = 0, 0\n",
    "        for instruct in instructions:\n",
    "            if instruct == 'G':\n",
    "                x += dirs[dirsIndex][0]\n",
    "                y += dirs[dirsIndex][1]\n",
    "            elif instruct == 'L':\n",
    "                dirsIndex -= 1\n",
    "                dirsIndex %= 4\n",
    "            else:\n",
    "                dirsIndex += 1\n",
    "                dirsIndex %= 4\n",
    "        return (x == 0 and y == 0) or dirsIndex != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        #north is 0; west is 1; south is 2; east is 3;\n",
    "        direction=0\n",
    "        #position\n",
    "        position=[0,0]\n",
    "        for i in instructions:\n",
    "            if i =='L':\n",
    "                direction+=1\n",
    "                direction=direction%4\n",
    "            elif i=='R':\n",
    "                direction-=1\n",
    "                direction=direction%4\n",
    "            else:\n",
    "                if direction==0:\n",
    "                    position[1]+=1\n",
    "                elif direction==1:\n",
    "                    position[0]-=1\n",
    "                elif direction==2:\n",
    "                    position[1]-=1\n",
    "                else:\n",
    "                    position[0]+=1\n",
    "        if position==[0,0]:\n",
    "            return True\n",
    "        elif direction!=0:\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # LL=dict()\n",
    "        # RR=dict()\n",
    "        # LL[str([0,1])]=[-1,0]\n",
    "        # LL[str([-1,0])]=[0,-1]\n",
    "        # LL[str([0,-1])]=[1,0]\n",
    "        # LL[str([1,0])]=[0,1]\n",
    "        # RR[str([0,1])]=[1,0]\n",
    "        # RR[str([1,0])]=[0,-1]\n",
    "        # RR[str([0,-1])]=[-1,0]\n",
    "        # RR[str([-1,0])]=[0,1]\n",
    "        direction=[[0,1],[-1,0],[0,-1],[1,0]]\n",
    "        dire=0\n",
    "        ls=[0,0]\n",
    "        pp=instructions\n",
    "        for each in pp:\n",
    "            if each==\"G\":\n",
    "                ls[0]+=direction[dire][0]\n",
    "                ls[1]+=direction[dire][1]\n",
    "            if each==\"L\":\n",
    "                dire-=1\n",
    "                dire%=4\n",
    "            if each==\"R\":\n",
    "                dire+=1\n",
    "                dire%=4\n",
    "        return ls==[0,0] or not (dire==0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def robotMove(self, position: list[int], dirction: tuple[str, int]) -> None:\n",
    "        match dirction[0]:\n",
    "            case 'x':\n",
    "                position[0] += dirction[1]\n",
    "            case 'y':\n",
    "                position[1] += dirction[1]\n",
    "\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        position = [0, 0]  # 记录机器人当前位置\n",
    "        dirction = [('x', 1), ('y', -1), ('x', -1), ('y', 1)]  # 坐标移动方式序列\n",
    "        pace = 0  # 当前移动方式\n",
    "        for i in instructions*4:\n",
    "            match i:\n",
    "                case 'G':\n",
    "                    self.robotMove(position, dirction[pace%4])\n",
    "                case 'L':\n",
    "                    pace += 1\n",
    "                case 'R':\n",
    "                    pace -= 1\n",
    "        return True if position == [0, 0] else False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k = 0\n",
    "        dist = [0] * 4\n",
    "        for i in instructions:\n",
    "            if i == 'L':\n",
    "                k = (k + 1) % 4\n",
    "            elif i == 'R':\n",
    "                k = (k + 3) % 4\n",
    "            else:\n",
    "                dist[k] += 1\n",
    "        return (dist[0] == dist[2] and dist[1] == dist[3]) or k != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # 找规律题\n",
    "        x, y, d = 0, 0, 0  # 初始化位置和方向,d=0表示面朝北方\n",
    "        dirs = [[0,1], [-1,0], [0,-1], [1,0]]\n",
    "        for c in instructions:\n",
    "            if c=='G':\n",
    "                x += dirs[d][0]\n",
    "                y += dirs[d][1]\n",
    "            elif c=='L':\n",
    "                d = (d+1)%4\n",
    "            else:\n",
    "                d = ((d-1)%4+4)%4\n",
    "        print(x,y,d)\n",
    "        return (x==0 and y==0) or d!=0\n",
    "        # 如果执行完一遍x=y=0,那么一定是个环，机器人无法离开\n",
    "        # 如果不能回到原点,那么讨论方向：\n",
    "        # 如果朝北d=0,那么再执行就会越来越远\n",
    "        # 如果朝西d=1,执行四次会形成循环\n",
    "        # 如果朝南d=2,再执行会变成(0,0),形成循环\n",
    "        # 如果朝东d=3,执行四次会形成循环\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k = 0\n",
    "        dist = [0] * 4\n",
    "        for c in instructions:\n",
    "            if c == 'L':\n",
    "                k = (k+1) % 4\n",
    "            elif c == 'R':\n",
    "                k = (k+3) % 4\n",
    "            else:\n",
    "                dist[k] += 1\n",
    "        return (dist[0]==dist[2] and dist[1] == dist[3]) or k != 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        tpl_dir = ((0,1), (1,0), (0,-1), (-1,0))\n",
    "        x,y=0,0\n",
    "        idx_dir = 0\n",
    "        \n",
    "        vec_dir = [0,1]\n",
    "        for ins in instructions:\n",
    "            if ins == 'G':\n",
    "                x += tpl_dir[idx_dir][0]\n",
    "                y += tpl_dir[idx_dir][1]\n",
    "            elif ins == 'L':\n",
    "                idx_dir = (idx_dir-1)%4\n",
    "            else:\n",
    "                idx_dir = (idx_dir+1)%4\n",
    "        return (x==0 and y==0) or idx_dir !=0\n",
    "\n",
    "                    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direc = [[0, 1], [1, 0], [0, -1], [-1, 0]]\n",
    "        direcIndex = 0\n",
    "        x, y = 0, 0\n",
    "        for instruction in instructions:\n",
    "            if instruction == 'G':\n",
    "                x += direc[direcIndex][0]\n",
    "                y += direc[direcIndex][1]\n",
    "            elif instruction == 'L':\n",
    "                direcIndex -= 1\n",
    "                direcIndex %= 4\n",
    "            else:\n",
    "                direcIndex += 1\n",
    "                direcIndex %= 4\n",
    "        return direcIndex != 0 or (x == 0 and y == 0)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:    \n",
    "        instructions = list(instructions)\n",
    "        face = 0\n",
    "        x, y = 0, 0\n",
    "        for w in instructions:\n",
    "            if w == 'G':\n",
    "                if face == 0: y += 1\n",
    "                if face == 1: x -= 1\n",
    "                if face == 2: x += 1\n",
    "                if face == 3: y -= 1\n",
    "            elif w == 'L':\n",
    "                if face == 0:\n",
    "                    face = 1\n",
    "                elif face == 1:\n",
    "                    face = 3\n",
    "                elif face == 3:\n",
    "                    face = 2\n",
    "                else:\n",
    "                    face = 0\n",
    "            elif w == 'R':\n",
    "                if face == 0:\n",
    "                    face = 2\n",
    "                elif face == 2:\n",
    "                    face = 3\n",
    "                elif face == 3:\n",
    "                    face = 1\n",
    "                else:\n",
    "                    face = 0\n",
    "            else:\n",
    "                pass\n",
    "        return x == y == 0 or face != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k=0\n",
    "        dot=[0,0,0,0]\n",
    "        for i in instructions:\n",
    "            if i=='L':\n",
    "                k=(k+1)%4\n",
    "            elif i=='R':\n",
    "                k=(k+3)%4\n",
    "            else:\n",
    "                dot[k]+=1\n",
    "        return (dot[0]==dot[2] and dot[1]==dot[3]) or k!=0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MOVE = ((0, 1), (1, 0), (0, -1), (-1, 0))\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x = y = 0\n",
    "        dire = 0   # 朝向\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x += MOVE[dire][0]\n",
    "                y += MOVE[dire][1]\n",
    "            elif i == 'R':\n",
    "                dire = (dire + 1) % 4\n",
    "            else:\n",
    "                dire = (dire - 1) % 4\n",
    "        return bool(dire) or (x == y == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k = 0\n",
    "        dist = [0] * 4\n",
    "        for c in instructions:\n",
    "            if c == 'L':\n",
    "                k = (k + 1) % 4\n",
    "            elif c == 'R':\n",
    "                k = (k + 3) % 4\n",
    "            else:\n",
    "                dist[k] += 1\n",
    "        return (dist[0] == dist[2] and dist[1] == dist[3]) or k != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k = 0\n",
    "        dist = [0] * 4\n",
    "        for c in instructions:\n",
    "            if c == 'L':\n",
    "                k = (k + 1) % 4\n",
    "            elif c == 'R':\n",
    "                k = (k + 3) % 4\n",
    "            else:\n",
    "                dist[k] += 1\n",
    "        return (dist[0] == dist[2] and dist[1] == dist[3]) or k != 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        k=0\n",
    "        disk = [0]*4\n",
    "        for c in instructions:\n",
    "            if c=='L':\n",
    "                k=(k+1)%4\n",
    "            elif c=='R':\n",
    "                k=(k+3)%4\n",
    "            else:\n",
    "                disk[k]+=1\n",
    "        return (disk[0]==disk[2] and disk[1]==disk[3]) or k!=0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direct_dxdy = ((0, 1), (1, 0), (0, -1), (-1, 0))\n",
    "        start = [0, 0]\n",
    "        position = [0, 0]\n",
    "        direct = 0 # 0123 -> NESW\n",
    "\n",
    "        for ins in instructions:\n",
    "            match ins:\n",
    "                case 'G':\n",
    "                    _dx, _dy = direct_dxdy[direct]\n",
    "                    position[0] += _dx\n",
    "                    position[1] += _dy\n",
    "                case 'L':\n",
    "                    direct = (direct - 1) % 4\n",
    "                case 'R':\n",
    "                    direct = (direct + 1) % 4\n",
    "        \n",
    "        return not ((direct == 0) and (start[0] != position[0] or start[1] != position[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # 如果机器人回到起点，不管面向何方都会进入环\n",
    "        # 4个方向 0 北，1东，2南，3西\n",
    "        direct = {\n",
    "            0:(-1,0),\n",
    "            1:(0,1),\n",
    "            2:(1,0),\n",
    "            3:(0,-1)\n",
    "        }\n",
    "        d = 0 # 当前方向\n",
    "        i = j = 0 # 起点坐标\n",
    "        for step in instructions*4:\n",
    "            if step == 'G': # 按照当前方向前进\n",
    "                i += direct[d][0]\n",
    "                j += direct[d][1]\n",
    "            elif step == 'R':\n",
    "                d = (d+1) % 4\n",
    "            else:\n",
    "                d = (d-1) % 4\n",
    "        return i==0 and j==0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x = y = 0\n",
    "        d = [0, 1]\n",
    "        for c in instructions:\n",
    "            if c == 'G':\n",
    "                x, y = x + d[0], y + d[1]\n",
    "            elif c =='L':\n",
    "                d = [-d[1], d[0]]\n",
    "            else:\n",
    "                d = [d[1], -d[0]]\n",
    "        return (x == 0 and y == 0) or d != [0, 1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        posix=posiy=0\n",
    "        incx=0\n",
    "        incy=1\n",
    "        t=0\n",
    "        for i in instructions:\n",
    "            if i=='G':\n",
    "                posix += incx\n",
    "                posiy += incy\n",
    "            elif i=='L':\n",
    "                t=incx\n",
    "                incx=-incy\n",
    "                incy=t\n",
    "            elif i=='R':\n",
    "                t=incx\n",
    "                incx=incy\n",
    "                incy=-t\n",
    "        if incx==0 and incy==1:\n",
    "            return(posix==0 and posiy==0)\n",
    "        else:return(True)\n",
    "\n",
    "   \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x, y, dx, dy = 0, 0, 0, 1\n",
    "\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x += dx\n",
    "                y += dy\n",
    "            elif i == 'L':\n",
    "                dx, dy = -dy, dx\n",
    "            else:\n",
    "                dx, dy = dy, -dx\n",
    "        \n",
    "        return (x, y) == (0, 0) or (dx, dy) != (0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # LL=dict()\n",
    "        # RR=dict()\n",
    "        # LL[str([0,1])]=[-1,0]\n",
    "        # LL[str([-1,0])]=[0,-1]\n",
    "        # LL[str([0,-1])]=[1,0]\n",
    "        # LL[str([1,0])]=[0,1]\n",
    "        # RR[str([0,1])]=[1,0]\n",
    "        # RR[str([1,0])]=[0,-1]\n",
    "        # RR[str([0,-1])]=[-1,0]\n",
    "        # RR[str([-1,0])]=[0,1]\n",
    "        direction=[[0,1],[-1,0],[0,-1],[1,0]]\n",
    "        dire=0\n",
    "        ls=[0,0]\n",
    "        pp=instructions\n",
    "        for each in pp:\n",
    "            if each==\"G\":\n",
    "                ls[0]+=direction[dire][0]\n",
    "                ls[1]+=direction[dire][1]\n",
    "            if each==\"L\":\n",
    "                dire-=1\n",
    "                dire%=4\n",
    "            if each==\"R\":\n",
    "                dire+=1\n",
    "                dire%=4\n",
    "        return ls==[0,0] or not (dire==0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)]\n",
    "        curr_dir_index = 0\n",
    "        curr_loc = (0, 0)\n",
    "\n",
    "        def take_a_step(curr_loc, curr_dir_index):\n",
    "            return (curr_loc[0] + dirs[curr_dir_index][0], curr_loc[1] + dirs[curr_dir_index][1])\n",
    "        \n",
    "        def turn_dir(curr_dir_index, turn_to):\n",
    "            if turn_to == 'L':\n",
    "                return (curr_dir_index+3)%4\n",
    "            else:\n",
    "                return (curr_dir_index+1)%4\n",
    "\n",
    "        for instr in instructions:\n",
    "            if instr == 'G':\n",
    "                curr_loc = take_a_step(curr_loc, curr_dir_index)\n",
    "            elif instr == 'L':\n",
    "                curr_dir_index = turn_dir(curr_dir_index, 'L')\n",
    "            elif instr == 'R':\n",
    "                curr_dir_index = turn_dir(curr_dir_index, 'R')\n",
    "            print(\"curr_loc, curr_dir_index\", curr_loc, curr_dir_index)\n",
    "        \n",
    "        return curr_loc == (0, 0) or curr_dir_index != 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def robotMove(self, position: list[int], dirction: tuple[str, int]) -> None:\n",
    "        match dirction[0]:\n",
    "            case 'x':\n",
    "                position[0] += dirction[1]\n",
    "            case 'y':\n",
    "                position[1] += dirction[1]\n",
    "\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        position = [0, 0]  # 记录机器人当前位置\n",
    "        dirction = [('x', 1), ('y', -1), ('x', -1), ('y', 1)]  # 坐标移动方式序列\n",
    "        pace = 0  # 当前移动方式\n",
    "        for i in instructions*4:  # 如果循环多次存在回路则四次后也会回到原点\n",
    "            match i:\n",
    "                case 'G':\n",
    "                    self.robotMove(position, dirction[pace%4])\n",
    "                case 'L':\n",
    "                    pace += 1\n",
    "                case 'R':\n",
    "                    pace -= 1\n",
    "        return True if position == [0, 0] else False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        instructions=instructions*4\n",
    "        plc=[0,0]\n",
    "        dire=[(1,0),(0,1),(-1,0),(0,-1)]\n",
    "        i=1\n",
    "        for w in instructions:\n",
    "            if w=='G':\n",
    "                plc[0]+=dire[i][0]\n",
    "                plc[1]+=dire[i][1]\n",
    "            elif w=='L':\n",
    "                i=(i+1)%4\n",
    "            else:\n",
    "                i=(i-1)%4\n",
    "        return plc==[0,0]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        LL=dict()\n",
    "        RR=dict()\n",
    "        LL[str([0,1])]=[-1,0]\n",
    "        LL[str([-1,0])]=[0,-1]\n",
    "        LL[str([0,-1])]=[1,0]\n",
    "        LL[str([1,0])]=[0,1]\n",
    "        RR[str([0,1])]=[1,0]\n",
    "        RR[str([1,0])]=[0,-1]\n",
    "        RR[str([0,-1])]=[-1,0]\n",
    "        RR[str([-1,0])]=[0,1]\n",
    "        dire=[0,1]\n",
    "        ls=[0,0]\n",
    "        pp=instructions*4\n",
    "        for each in pp:\n",
    "            if each==\"G\":\n",
    "                ls[0]+=dire[0]\n",
    "                ls[1]+=dire[1]\n",
    "            if each==\"L\":\n",
    "                dire=LL[str(dire)]\n",
    "            if each==\"R\":\n",
    "                dire=RR[str(dire)]\n",
    "        return ls==[0,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dirs = [(0, 1), (-1, 0), (0, -1), (1, 0)]\n",
    "        pos, ind = [0,0], 0\n",
    "        for s in instructions:\n",
    "            if s == 'G':\n",
    "                pos[0], pos[1] = pos[0] + dirs[ind][0], pos[1] + dirs[ind][1]\n",
    "            if s == 'L':\n",
    "                ind = (ind + 1)%4\n",
    "            elif s == 'R':\n",
    "                ind = (ind - 1)%4\n",
    "            print(pos, ind)\n",
    "        return (pos[0] == 0 and pos[1] == 0) or ind != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x, y, d = 0, 0, 0  # 初始化位置和方向,d=0表示面朝北方\n",
    "        dirs = [[0,1], [-1,0], [0,-1], [1,0]]\n",
    "        for c in instructions:\n",
    "            if c=='G':\n",
    "                x += dirs[d][0]\n",
    "                y += dirs[d][1]\n",
    "            elif c=='L':\n",
    "                d = (d+1)%4\n",
    "            else:\n",
    "                d = ((d-1)%4+4)%4\n",
    "        print(x,y,d)\n",
    "        return (x==0 and y==0) or d!=0\n",
    "        # 如果执行完一遍x=y=0,那么一定是个环，机器人无法离开\n",
    "        # 如果不能回到原点,那么讨论方向：\n",
    "        # 如果朝北d=0,那么再执行就会越来越远\n",
    "        # 如果朝西d=1,执行四次会形成循环\n",
    "        # 如果朝南d=2,再执行会变成(0,0),形成循环\n",
    "        # 如果朝东d=3,执行四次会形成循环\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        \n",
    "        directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]  \n",
    "        x, y = 0, 0  \n",
    "        direction_index = 0  \n",
    "\n",
    "        for instruction in instructions:\n",
    "            if instruction == \"G\":\n",
    "                x += directions[direction_index][0]\n",
    "                y += directions[direction_index][1]\n",
    "            elif instruction == \"L\":\n",
    "                direction_index = (direction_index - 1) % 4\n",
    "            elif instruction == \"R\":\n",
    "                direction_index = (direction_index + 1) % 4\n",
    "\n",
    "        return (x == 0 and y == 0) or direction_index != 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        self.QS = [(0,1),(1,0),(0,-1),(-1,0)]\n",
    "        self.Q=0\n",
    "        local = (0,0)\n",
    "        for ins in instructions:\n",
    "            if ins=='R':\n",
    "                if self.Q!=3:\n",
    "                    self.Q+=1\n",
    "                else:\n",
    "                    self.Q=0\n",
    "            elif ins=='L':\n",
    "                if self.Q!=0:\n",
    "                    self.Q-=1\n",
    "                else:\n",
    "                    self.Q=3\n",
    "            else:\n",
    "                local = (local[0]+self.QS[self.Q][0],local[1]+self.QS[self.Q][1])\n",
    "        if local[0]==0 and local[1]==0:\n",
    "            return True\n",
    "        if self.Q == 0:\n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        # 不看G L 和 R的数目如果必须是小于4个L中间插入4个R,当确定四个R或L之后就成环了\n",
    "        # if 'R' in instructions and 'L' not in instructions:\n",
    "        #     return True\n",
    "        # if 'L' in instructions and 'R' not in instructions:\n",
    "        #     return True\n",
    "        # if 'R' not in instructions and 'L' not in instructions:\n",
    "        #     return False\n",
    "        # countl,countr = 0, 0\n",
    "        # count = 0\n",
    "        # for c in instructions:\n",
    "        #     if count >= 4 and count <= -4:\n",
    "        #         return True\n",
    "        #     if c == 'R':\n",
    "        #         count -= 1\n",
    "        #     elif c == 'L':\n",
    "        #         count += 1\n",
    "        # if count == 0:\n",
    "        #     return False\n",
    "        # else:\n",
    "        #     return True\n",
    "        # 机器人想要摆脱循环，在遗传指令之后的状态必须是不位于原点且方向朝北\n",
    "        direc = [[0,1],[1,0],[0,-1],[-1,0]]\n",
    "        direcIndex = 0\n",
    "        x,y = 0,0\n",
    "        for instruction in instructions:\n",
    "            if instruction == \"G\":\n",
    "                x += direc[direcIndex][0]\n",
    "                y += direc[direcIndex][1]\n",
    "            elif instruction == \"L\":\n",
    "                direcIndex -= 1\n",
    "                direcIndex %= 4\n",
    "            else:\n",
    "                direcIndex += 1\n",
    "                direcIndex %= 4\n",
    "        return direcIndex != 0 or(x== 0 and y == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        x = 0\n",
    "        y = 0\n",
    "        instructions = instructions\n",
    "        direction = 'north'\n",
    "\n",
    "        for i in instructions:\n",
    "            if i == 'L':\n",
    "                match direction:\n",
    "                    case 'north':\n",
    "                        direction = 'west'\n",
    "                    case 'west':\n",
    "                        direction = 'south'\n",
    "                    case 'south':\n",
    "                        direction = 'east'\n",
    "                    case 'east':\n",
    "                        direction = 'north'\n",
    "                print(i, direction, x, y)\n",
    "            elif i == 'R':\n",
    "                match direction:\n",
    "                    case 'north':\n",
    "                        direction = 'east'\n",
    "                    case 'west':\n",
    "                        direction = 'north'\n",
    "                    case 'south':\n",
    "                        direction = 'west'\n",
    "                    case 'east':\n",
    "                        direction = 'south'\n",
    "                print(i, direction, x, y)\n",
    "\n",
    "            else:\n",
    "                match direction:\n",
    "                    case 'north':\n",
    "                        y += 1\n",
    "                    case 'west':\n",
    "                        x -= 1\n",
    "                    case 'south':\n",
    "                        y -= 1\n",
    "                    case 'east':\n",
    "                        x += 1\n",
    "                print(i, direction, x, y)\n",
    "        if (x == 0 and y == 0) or (direction in (['south','east','west'])):\n",
    "            return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dx = [0, 1, 0,  -1]\n",
    "        dy = [1, 0, -1, 0]\n",
    "        x , y = 0, 0\n",
    "        fx = 0 #北 \n",
    "        for i in range(4):\n",
    "            for c in instructions:\n",
    "                if c == 'G':\n",
    "                    x += dx[fx]\n",
    "                    y += dy[fx]\n",
    "                elif c == 'L':\n",
    "                    fx = (fx - 1)%4\n",
    "                elif c == 'R':\n",
    "                    fx = (fx + 1)%4\n",
    "        if x == 0 and y == 0 :\n",
    "            return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "dr = [[0,1], [1, 0], [0,-1], [-1, 0]]\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        ortidr = 0\n",
    "        x, y = 0, 0\n",
    "\n",
    "        for i in instructions:\n",
    "            if i == 'G':\n",
    "                x, y = x + dr[ortidr][0], y + dr[ortidr][1]\n",
    "            elif i == 'L':\n",
    "                ortidr -= 1\n",
    "                ortidr %= 4\n",
    "            elif i == 'R':\n",
    "                ortidr += 1\n",
    "                ortidr %= 4\n",
    "        return ortidr != 0 or (x == 0 and y == 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dic=[[0,1],[1,0],[0,-1],[-1,0]]\n",
    "        idx=0\n",
    "        x,y=0,0\n",
    "        for i in instructions:\n",
    "            if i=='G':\n",
    "                x+=dic[idx][0]\n",
    "                y+=dic[idx][1]\n",
    "            elif i=='L':\n",
    "                idx-=1\n",
    "                idx%=4\n",
    "            else:\n",
    "                idx+=1\n",
    "                idx%=4\n",
    "        return idx!=0 or (x==0 and y==0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # detect any circle \n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]\n",
    "        cur_dir = 0\n",
    "        cur_pos = [0, 0]\n",
    "        for c in instructions:\n",
    "            # iterate through every element\n",
    "            if c == 'G':\n",
    "                cur_pos = [cur_pos[0] + dir[cur_dir][0], cur_pos[1] + dir[cur_dir][1]]\n",
    "            if c == 'L':\n",
    "                cur_dir -= 1\n",
    "                cur_dir = cur_dir % 4\n",
    "            if c == 'R':\n",
    "                cur_dir += 1\n",
    "                cur_dir = cur_dir % 4\n",
    "        if cur_pos != [0, 0] and cur_dir == 0:\n",
    "            return False\n",
    "        else:\n",
    "            return True\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        direct = [[0,1], [1,0], [0,-1], [-1,0]]\n",
    "        d_index = 0\n",
    "        site = [0,0]\n",
    "        for i in instructions:\n",
    "            if i == \"L\":\n",
    "                d_index = (d_index-1)%4\n",
    "            elif i == \"R\":\n",
    "                d_index = (d_index+1)%4\n",
    "            else:\n",
    "                site[0] += direct[d_index][0]\n",
    "                site[1] += direct[d_index][1]\n",
    "            \n",
    "        if d_index == 0 and site != [0,0]:\n",
    "            return False\n",
    "        else:\n",
    "            return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isRobotBounded(self, instructions: str) -> bool:\n",
    "        face = 0\n",
    "        position = [0, 0]\n",
    "        for ch in instructions:\n",
    "            if ch == 'L':\n",
    "                if face == 0:\n",
    "                    face = 3\n",
    "                else:\n",
    "                    face -= 1\n",
    "            elif ch == 'R':\n",
    "                if face == 3:\n",
    "                    face = 0\n",
    "                else:\n",
    "                    face += 1\n",
    "            else:\n",
    "                if face == 0:\n",
    "                    position[1] += 1\n",
    "                elif face == 1:\n",
    "                    position[0] += 1\n",
    "                elif face == 2:\n",
    "                    position[1] -= 1\n",
    "                else:\n",
    "                    position[0] -= 1\n",
    "        if position == [0, 0]:\n",
    "            return True\n",
    "        elif face != 0:\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
